package com.authentications.filter;

import com.authentications.filter.info.UrlPathWhiteValue;
import com.authentications.filter.unrealizeds.JWTGainProcessor;
import com.authentications.utils.JWTUtils;
import io.jsonwebtoken.ExpiredJwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @ClassName WholeRequestFilter
 * @Author xiezhuocai
 * @Description TODO
 * @Date 2021/12/15 9:28
 */
public class WholeRequestFilter implements Filter {

    private Logger logger = LoggerFactory.getLogger(WholeRequestFilter.class);

    //默认提供的登录接口
    private static final String DEFAULT_LOGIN_PSTH = "/login";

    //默认认证头
    private static final String DEFAULT_WHITE_HEAD = "Authentication";

    //白名单设置
    private UrlPathWhiteValue whiteValue;

    public WholeRequestFilter(UrlPathWhiteValue whiteValue) {
        this.whiteValue = whiteValue;
    }


    /**
     * @Author xiezhuocai
     * @Description //需要判断head里是否带有认证信息
     * @Date 2021/12/15 10:09
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setCharacterEncoding("UTF-8");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        request.setCharacterEncoding("UTF-8");
        String requestURI = ((HttpServletRequest) servletRequest).getRequestURI();
        logger.info("入参URI:"+requestURI);
        if (requestURI.equals(DEFAULT_LOGIN_PSTH)||whiteValue.getWhiteList().contains(requestURI)) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            String examine = isExamine(request);
            logger.info("认证信息:"+examine);
            if (!StringUtils.isEmpty(examine)) {
                try {
                    parseJWT(examine);
                    filterChain.doFilter(servletRequest,servletResponse);
                } catch (ExpiredJwtException e){
                    notAuthent(response);
                }
            } else {
                notAuthent(response);
            }
        }

    }

    /**
     * @Author xiezhuocai
     * @Description //解析token
     * @Date 2021/12/15 15:28
     */
    public void parseJWT(String token){
        String expectToken = JWTUtils.parseToken(token);
        logger.info("解析token:"+expectToken);
        JWTGainProcessor gainProcessor = new JWTGainProcessor();
        gainProcessor.gain(expectToken);
    }

    /**
     * @Author xiezhuocai
     * @Description //是否带有请求头
     * @Date 2021/12/15 15:28
     */
    public String isExamine(HttpServletRequest servletRequest){
        String examineHeader = null;
        if (!StringUtils.isEmpty(whiteValue.getHead())) { //认证头设置不为null
            examineHeader = servletRequest.getHeader(whiteValue.getHead());
        } else {
            examineHeader = servletRequest.getHeader(DEFAULT_WHITE_HEAD);
        }

        if (StringUtils.isEmpty(examineHeader)) {
            return null;
        }
        return examineHeader;
    }

    /**
     * @Author xiezhuocai
     * @Description //未认证返回信息
     * @Date 2021/12/15 15:51
     * @Param
     * @return
     */
    public void notAuthent(HttpServletResponse response) throws IOException {
        response.setStatus(500);
        PrintWriter writer = response.getWriter();
        writer.print("认证失败");
        writer.close();
        response.flushBuffer();
    }

}
